﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace TinyCms.Core.Repositories
{
    public abstract class Repository<T>:IRepository<T> where T:EntityBase
    {
        private readonly IRepositoryContext _context;

        protected Repository(IRepositoryContext context)
        {
            _context = context;
        }

        public IRepositoryContext Context
        {
            get { return _context; }
        }

#region abstract methods
//此处抽象出这些方法让派生类去实现，比派生类直接继承IRepository的好处是
//更少的实现
        protected abstract T DoGetByKey(Guid id);

        protected abstract IEnumerable<T> DoGetAll(Expression<Func<T, bool>> pre, Expression<Func<T, dynamic>> sort,
                                                   SortOrder order = SortOrder.Ascending);

        protected abstract IEnumerable<T> DoGetPageList(int pageIndex, int pagesize, out int count,
                                                        Expression<Func<T, bool>> pre, Expression<Func<T, dynamic>> sort,
                                                        SortOrder order = SortOrder.Ascending);

        protected abstract void DoAdd(List<T> entities);

        protected abstract void DoUpdate(List<T> entities);

        protected abstract void DoDelete(List<T> entities);

        protected abstract int DoExecuteCommand(string command);

        protected abstract IEnumerable<T> DoExecuteQuery(string command); 

#endregion
        public T GetByKey(Guid id)
        {
            return DoGetByKey(id);
        }

        public IEnumerable<T> GetAll()
        {
            return DoGetAll(null, null);
        }

        public IEnumerable<T> GetAll(Expression<Func<T, dynamic>> sort, SortOrder order = SortOrder.Ascending)
        {
            return DoGetAll(null, sort, order);
        }

        public IEnumerable<T> GetAll(Expression<Func<T, bool>> pre)
        {
            return DoGetAll(pre, null);
        }

        public IEnumerable<T> GetAll(Expression<Func<T, bool>> pre, Expression<Func<T, dynamic>> sort, SortOrder order = SortOrder.Ascending)
        {
            return DoGetAll(pre, sort, order);
        }

        public IEnumerable<T> GetPageList(int pageIndex, int pagesize, out int count, Expression<Func<T, bool>> pre)
        {
            return DoGetPageList(pageIndex, pagesize, out count, pre, null);
        }

        public IEnumerable<T> GetPageList(int pageIndex, int pagesize, out int count, Expression<Func<T, bool>> pre, Expression<Func<T, dynamic>> sort, SortOrder order = SortOrder.Ascending)
        {
            return DoGetPageList(pageIndex, pagesize, out count, pre, sort, order);
        }

        public void Add(T entity)
        {
            DoAdd(new List<T> {entity});
        }

        public void Add(List<T> entities)
        {
            DoAdd(entities);
        }

        public void Update(T entity)
        {
            DoUpdate(new List<T> {entity});
        }

        public void Update(List<T> entity)
        {
            DoUpdate(entity);
        }

        public void Delete(T entity)
        {
            DoDelete(new List<T>{entity});
        }

        public void Delete(List<T> entity)
        {
            DoDelete(entity);
        }

        /// <summary>
        /// 直接执行t-sql命令
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public int ExecuteCommand(string command)
        {
            return DoExecuteCommand(command);
        }

        /// <summary>
        /// 直接执行t-sql查询
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public IEnumerable<T> ExecuteQuery(string query)
        {
            return DoExecuteQuery(query);
        }
    }
}
